package com.ishare.api.service.face.impl;

import com.ishare.api.po.login.*;
import com.ishare.api.service.face.LoginFaceService;
import com.ishare.api.vo.login.RepeatedRegisterVo;
import com.ishare.api.vo.user.UserVo;
import com.ishare.common.constant.LoginReturnCode;
import com.ishare.common.constant.ScoreChangeType;
import com.ishare.common.constant.UserLevel;
import com.ishare.common.entity.User;
import com.ishare.common.service.base.EmailService;
import com.ishare.common.service.base.ScoreService;
import com.ishare.common.service.base.TokenService;
import com.ishare.common.service.base.UserService;
import com.ishare.common.utils.RandomUtils;
import com.ishare.common.utils.ShareCodeUtil;
import com.ishare.common.utils.SnowflakeIdUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;

/**
 * @author 李嘉宾
 */
@Service
public class LoginFaceServiceImpl implements LoginFaceService {

    @Resource
    private UserService userService;

    @Resource
    private TokenService tokenService;

    @Resource
    private EmailService emailService;

    @Resource
    private ScoreService scoreService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserVo registerSubmit(UserRegisterParam userRegisterParam) {
        //判断验证码是否正确
        String email = userRegisterParam.getEmail();
        String emailCodeFromCache = emailService.getEmailCodeFromCache(email);
        if (StringUtils.isEmpty(emailCodeFromCache)) {
            throw LoginReturnCode.EMAIL_CODE_ERROR.createException();
        }
        if (!emailCodeFromCache.equals(userRegisterParam.getEmailCode())) {
            throw LoginReturnCode.EMAIL_CODE_ERROR.createException();
        }
        emailService.clearEmailCodeFromCache(userRegisterParam.getEmail());
        //查询用户是否存在
        User userByUserName = userService.getUserByUserName(userRegisterParam.getUserName());
        if (userByUserName != null) {
            throw LoginReturnCode.REPEAT_USER_NAME_REGISTER.createException();
        }
        //查询邮箱是否存在
        User userByEmail = userService.getUserByEmail(userRegisterParam.getEmail());
        if (userByEmail != null) {
            throw LoginReturnCode.REPEAT_EMAIL_REGISTER.createException();
        }
        SnowflakeIdUtils snowflakeIdUtils = new SnowflakeIdUtils(0, 0);
        //构建用户基础信息
        User insertUser = userService.insertUser(User.builder().email(userRegisterParam.getEmail())
                .password(userRegisterParam.getPassword())
                .username(userRegisterParam.getUserName())
                .score(0L)
                .level(UserLevel.LEVEL_NORMAL)
                .promoteCode(ShareCodeUtil.toSerialCode(snowflakeIdUtils.nextId())).build());

        //新注册用户发放10积分
        scoreService.changeUserScore(ScoreChangeType.NEW_USER_ADD,10L,0,insertUser.getId());
        //构建返回对象
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(insertUser, userVo);
        String randomToken = RandomUtils.randomToken();
        tokenService.refreshToken(insertUser.getId(), randomToken);
        userVo.setToken(randomToken);
        return userVo;
    }

    @Override
    public UserVo loginSubmit(UserLoginParam userLoginParam) {
        String emailOrUserName = userLoginParam.getEmailOrUserName();
        String password = userLoginParam.getPassword();

        //通过邮箱查询用户是否存在
        User findUser = userService.getUserByEmail(emailOrUserName);
        if(findUser == null){
            findUser = userService.getUserByUserName(emailOrUserName);
        }
        if(findUser == null){
            //用户不存在 报错
            throw LoginReturnCode.PASSWORD_ERROR.createException();
        }
        //用户名存在 判断密码是否一致
        String dbPassword = findUser.getPassword();
        if(!dbPassword.equals(password)){
            //密码不匹配
            throw LoginReturnCode.PASSWORD_ERROR.createException();
        }
        //登录成功 生成Token
        String randomToken = RandomUtils.randomToken();
        tokenService.refreshToken(findUser.getId(),randomToken);
        //构建返回参数
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(findUser,userVo);
        userVo.setToken(randomToken);
        return userVo;
    }

    @Override
    public void sendEmailCode(UserGetEmailCodeParam userGetEmailCodeParam) {
        //是否注册过
        User userByEmail = userService.getUserByEmail(userGetEmailCodeParam.getEmail());
        if (userByEmail != null) {
            throw LoginReturnCode.REPEAT_EMAIL_REGISTER.createException();
        }
        //是否是频繁发送
        Long emailCodeTimeOutValue = emailService.getEmailCodeTimeOutValue(userGetEmailCodeParam.getEmail());
        if (emailCodeTimeOutValue != null && emailCodeTimeOutValue > 60 * 2) {
            throw LoginReturnCode.EMAIL_SEND_REPEATED.createException();
        }
        String cacheCode = RandomUtils.randomCode();
        boolean sendEmailCode = emailService.sendEmailCode(userGetEmailCodeParam.getEmail(), cacheCode);
        if (sendEmailCode) {
            //保存到缓存中
            emailService.saveEmailCodeCache(userGetEmailCodeParam.getEmail(), cacheCode);
        } else {
            throw LoginReturnCode.EMAIL_SEND_ERROR.createException();
        }
    }

    @Override
    public RepeatedRegisterVo checkEmailIsRepeated(CheckEmailRepeatedRegisterParam checkEmailRepeatedRegisterParam) {
        RepeatedRegisterVo repeatedRegisterVo = new RepeatedRegisterVo();
        User userByEmail = userService.getUserByEmail(checkEmailRepeatedRegisterParam.getEmail());
        if(userByEmail == null){
            repeatedRegisterVo.setIsRepeated(false);
        }else{
            repeatedRegisterVo.setIsRepeated(true);
        }
        return repeatedRegisterVo;
    }

    @Override
    public RepeatedRegisterVo checkUserNameIsRepeated(CheckUserNameRepeatedRegisterParam checkUserNameRepeatedRegisterParam) {
        RepeatedRegisterVo repeatedRegisterVo = new RepeatedRegisterVo();
        User userByUserName = userService.getUserByUserName(checkUserNameRepeatedRegisterParam.getUserName());
        repeatedRegisterVo.setIsRepeated(userByUserName != null);
        return repeatedRegisterVo;
    }
}
